/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mygameframework.isoengine;

import com.mygameframework.util.Utility;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 *
 * @author bill
 */
public class TileSet {
    public int cTransparency;
    public boolean transparent;
    public TileInfo[] tileInfos;
    int tileCount;
    public BufferedImage timg;

    public TileSet(int cTransparency) {
        this.cTransparency = cTransparency;
        transparent=true;
    }
    
    
    public  void load(String file) throws IOException{
        timg=Utility.getCompatibleBufferedImage(file);
        int w=timg.getWidth();
        int h=timg.getHeight();
//        BufferedImage temp=Utility.copyImage(timg);
        //使用约定的图像格式才有效
        int ctransparent=timg.getRGB(w-1, 0);
        int cwall=timg.getRGB(w-1, 1);
        int cAnchor=timg.getRGB(w-1, 2);
        int cinside=timg.getRGB(w-1, 3);
        int cInsideAnchor=timg.getRGB(w-1, 4);
        
        int ctest=0;
        
        int hCellWallCount=0;
        int xcount;
        int vCellWallCount=0;
        int ycount;
        int cc=0x00FFFFFF;
        // TODO 切记 发布时要去掉
        timg.setRGB(0, h-1, ctransparent);//修正原图 
        
        for(xcount=0;xcount<w;xcount++){
            ctest=timg.getRGB(xcount, 0);
            if(ctest==ctransparent){
                hCellWallCount++;
            }
        }
        int[] hCellWall=new int[hCellWallCount];
        hCellWallCount=0;
        for(xcount=0;xcount<w;xcount++){
            ctest=timg.getRGB(xcount, 0);
            if(ctest==ctransparent){
                hCellWall[hCellWallCount]=xcount;
                hCellWallCount++;
            }
        }
        for(ycount=0;ycount<h;ycount++){
            ctest=timg.getRGB(0, ycount);
            if(ctest==ctransparent){
                vCellWallCount++;
            }
        }
        int[] vCellWall=new int[vCellWallCount];
        vCellWallCount=0;
        for(ycount=0;ycount<h;ycount++){
            ctest=timg.getRGB(0, ycount);
            if(ctest==ctransparent){
                vCellWall[vCellWallCount]=ycount;
                vCellWallCount++;
            }
        }
        for(int i:vCellWall){
            System.out.println("[ts.load]垂直方向墙的位置:"+i);
        }
        System.out.println("h cellwall.len"+hCellWall.length);
        System.out.println("v cellwall.len"+vCellWall.length);
	//calculate number of rows, number of columns, and number of tiles
	int tilerows=vCellWallCount-1;//垂直向的墙数-1就是tile数
	int tilecolumns=hCellWallCount-1;//水平方向的墙数-1
	int tilenum=0;
        tileCount=tilerows*tilecolumns;//素材图的tile总数 0起
        System.out.println("总tiles:"+tileCount);
        tileInfos=new TileInfo[tileCount];
        for(int r=0;r<tilerows;r++){
            for(int c=0;c<tilecolumns;c++){
                //tile number
                //从左到右,至上而下的为每个tile遍号,
                //注,这里指是'tile元' 即每个tile樣子是唯一的
                tilenum = c + r * tilecolumns;
                tileInfos[tilenum]=new TileInfo();
                //temporary flag variable
                boolean found = false;
                //scan top
                ycount = vCellWall[r]; //当前r的坐标
                //scan top for anchor
                found = false;/*即当found为true,就退出循环*/
                //横向找各cellwall 的anchar的x位置
                for (xcount = hCellWall[c] + 1; (!found) && (xcount < hCellWall[c + 1] - 1); xcount++) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);

                    //check pixel for anchor
                    if ((ctest == cAnchor) || (ctest == cInsideAnchor)) {
                        found = true;//即找到anchor就退出for
                        //可见anchor的定义是根据anchor或insideAnchor色块位置
                        tileInfos[tilenum].anchor.x = xcount;
                    }
                }//anchor.x和src.x的条件都有cInsideAnchor ,可见,他们x有机会相同
                found=false;
                for (xcount = hCellWall[c] + 1; (!found) && (xcount < hCellWall[c + 1] - 1); xcount++) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);
                    //check pixel for anchor
                    if ((ctest == cinside) || (ctest == cInsideAnchor)) {
                        tileInfos[tilenum].src.x=xcount;
                    }
                }
                //not found, use default
                //如果横向 地从墙坐标x+1开始,没找到inside或InsideAnchor 的颜色,就按墙+1的坐标是left
                if (!found) {
                    tileInfos[tilenum].src.x = hCellWall[c] + 1;
                }
                found=false;
                
                for (xcount = hCellWall[c+1]-1; (!found) && (xcount >= hCellWall[c ] +1); xcount--) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);
                    //check pixel for anchor
                    if ((ctest == cinside) || (ctest == cInsideAnchor)) {
                        int srcw=xcount-tileInfos[tilenum].src.x+1;
                        if(srcw>=1){
                            found=true;
                            tileInfos[tilenum].src.width=srcw;
                        }
                    }
                }
                if (!found) {
                    tileInfos[tilenum].src.width = hCellWall[c+1] -tileInfos[tilenum].src.x;
                }
                
                xcount=hCellWall[c]; //从墙的竖向找色块 
                found=false;
                for (ycount = vCellWall[r ] + 1; (!found) && (ycount < vCellWall[r+ 1]-1 ); ycount++) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);
                    //check pixel for anchor
                    if ((ctest == cAnchor) || (ctest == cInsideAnchor)) {
                            found = true;
                            tileInfos[tilenum].anchor.y = ycount;
                    }
                }
                 found=false;
                for (ycount = vCellWall[r ] + 1; (!found) && (ycount < vCellWall[r+ 1]-1 ); ycount++) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);
                    //check pixel for anchor
                    if ((ctest == cinside) || (ctest == cInsideAnchor)) {
                            found = true;
                            tileInfos[tilenum].src.y = ycount;
                    }
                }
                if(!found){
                    tileInfos[tilenum].src.y = vCellWall[r]+1;
                }
                 found=false;
                for (ycount = vCellWall[r +1] -1; (!found) && (ycount >= vCellWall[r]+1 ); ycount--) {
                    //grab pixel
                    ctest = timg.getRGB(xcount, ycount);
                    //check pixel for anchor
                    if ((ctest == cinside) || (ctest == cInsideAnchor)) {
                        int srch = ycount - tileInfos[tilenum].src.y + 1;
                        if (srch >= 1) {
                            found = true;
                            tileInfos[tilenum].src.height = srch;
                        }
                    }
                }
                if(!found){
                    tileInfos[tilenum].src.height=vCellWall[r+1]-tileInfos[tilenum].src.y;
                }
//                tileInfos[tilenum].dstExt=(Rectangle) tileInfos[tilenum].src.clone();
                tileInfos[tilenum].dstExt=new Rectangle(tileInfos[tilenum].src);
                int dx=tileInfos[tilenum].anchor.x;//anchor.x==src.x时
                int dy=tileInfos[tilenum].anchor.y;//anchor.y==src.y时
                tileInfos[tilenum].dstExt.translate(-dx, -dy);//dstExt左上角在源点(0,0)
                /**
                 * src rect java.awt.Rectangle[x=1,y=1,width=64,height=32] 
                 * dst rect java.awt.Rectangle[x=-31,y=-15,width=64,height=32]
                 * anchor java.awt.Point[x=32,y=16]

                 */
                System.out.println("src rect "+tileInfos[tilenum].src);
                System.out.println("dst rect "+tileInfos[tilenum].dstExt);
                System.out.println("anchor "+tileInfos[tilenum].anchor);
                System.out.println("");
            }//end for
        }//end for
//        int b=timg.getRGB(5, 5)&0xFFFFFF;//
        //指定颜色转成透明
        if(transparent)
            timg=Utility.replaceColor(timg, cTransparency, 0x00FFFFFF);
    }
    public static class TileInfo{
        
        public Point anchor;
        public Rectangle src;
        //dstExt.x 其实是一个打印偏移量,
        public Rectangle dstExt;//dstExt的XY是=(内容 或 内锚标)-(外锚标 或 内锚标)

        public TileInfo() {
            anchor =new Point();
            src=new Rectangle();
            dstExt=new Rectangle();
        }
        
        
    }
    
    

    public static void createAndShowGUI() throws IOException {
        
//        System.out.println(timg.getWidth());
        JFrame f=new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(600, 400);
//        p.setSize(600, 400);
//        f.setLayout(new BorderLayout());
//        p.add(new JButton("d"));
        f.add(new JPanel(){
            
         @Override
            public void paintComponent(Graphics g) {
                Graphics2D g2=(Graphics2D)g;
                g.setColor(Color.red);
                g.fillRect(0, 0, 50, 50);
//                System.out.println(timg.getWidth());
//                g.drawImage(timg, 50, 50, this);
//                g.drawImage(timg, 40, 50, this);
            }
        });
//        f.add(new JTextField("ddd"));
        f.setVisible(true);
    }
    /**
     * 
     * @param g2
     * @param givenClip 要渲染的区域(在screenSpace内)
     * @param xDst 打印的坐标X
     * @param yDst
     * @param tileNum
     * @return 
     */
    public boolean efficientPut(Graphics2D g2,Rectangle givenClip,int xDst,int yDst
            ,int tileNum){
        Rectangle rcSrc;
        Rectangle rcDst;
        int diffX,diffY;
//        rcDst=(Rectangle) this.tileInfos[tileNum].dstExt.clone();//clone占用大量时间
        rcDst=new Rectangle(this.tileInfos[tileNum].dstExt);

//        rcDst.setLocation(xDst, yDst);
        rcDst.translate(xDst, yDst);
        if(rcDst.intersects(givenClip)){
            diffX=this.tileInfos[tileNum].src.x-rcDst.x;
            diffY=this.tileInfos[tileNum].src.y-rcDst.y;
            rcDst=rcDst.intersection(givenClip);
//            rcSrc=(Rectangle) rcDst.clone();//clone占用大量时间
            rcSrc=new Rectangle(rcDst);
            rcSrc.translate(diffX, diffY);

            int dx1 = rcDst.x;
            int dy1 = rcDst.y;
            int dx2 = (int) rcDst.getMaxX();
            int dy2 = (int) rcDst.getMaxY();
            int sx1 = rcSrc.x;
            int sy1 = rcSrc.y;
            int sx2 = (int) rcSrc.getMaxX();
            int sy2 = (int) rcSrc.getMaxY();
            g2.drawImage(timg, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
        }else{
            return false;
        }
        return true;

    }
    public void put(Graphics2D g,int dstx,int dsty,int num){
        tileInfos[num].dstExt.translate(dstx, dsty);
        //setLocation 会让anchor失效
//        Rectangle old=(Rectangle) tileInfos[num].dstExt.clone();
//        tileInfos[num].dstExt.setLocation(dstx, dsty);

        int dx1=tileInfos[num].dstExt.x;
        int dy1=tileInfos[num].dstExt.y;
        int dx2=(int) tileInfos[num].dstExt.getMaxX();
        int dy2=(int) tileInfos[num].dstExt.getMaxY();
        int sx1=tileInfos[num].src.x;
        int sy1=tileInfos[num].src.y;
        int sx2=(int) tileInfos[num].src.getMaxX();
        int sy2=(int) tileInfos[num].src.getMaxY();
        
        g.drawImage(timg, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
//        tileInfos[num].dstExt=old;
        tileInfos[num].dstExt.translate(-dstx, -dsty);
    }
    /**返回贴图的数量(非地图格子数)*/
    public int getTileCount(){
        return this.tileCount;
}
    public TileInfo[] getInfos(){
        return this.tileInfos;
    }
    public static void main(String[] args) throws IOException {
        TileSet t=new TileSet(0x000000);
        t.load("images/IsoHex12_3-2.bmp");
        System.out.println(-32%64);
        Runnable doCreateAndShowGUI = new Runnable() {

            public void run() {
                try {
                    createAndShowGUI();
                } catch (IOException ex) {
                    Logger.getLogger(TileSet.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        SwingUtilities.invokeLater(doCreateAndShowGUI);
    }
}
